package com.dtwave.wechat.service.provider.core.filter;

import com.dtwave.wechat.service.provider.common.utils.HttpUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.AdviceFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;


/**
 * @Type LoginFilter.java 
 * @Desc 扩展AdviceFilter，用户过滤掉带有请求头的ajax的跨域请求的option请求
 * （因为option请求没有登录令牌，会导致shiro走原生的cookie会话验证，从而使得redis产生无用的记录）
 * @author lwx 
 * @date
 * @version  
 */  
public class ShiroLoginFilter extends AdviceFilter {

	
	private static final Logger log = LoggerFactory.getLogger(ShiroLoginFilter.class);
	 /**
     * 在访问controller前判断是否为ajax预请求
     * @param request
     * @param response
     * @return true-继续往下执行，false-该filter过滤器已经处理，不继续执行其他过滤器
     * @throws Exception
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        log.info("1.preHandle,请求的uri:[{}],请求类型:[{}],是否为ajax请求：[{}]", httpServletRequest.getRequestURI(),httpServletRequest.getMethod(), HttpUtil.isAxaxRequest(request));
        if(httpServletRequest.getMethod().equals("OPTIONS")){
        	log.info("2.preHandle:跨域的ajax请求的(option)预请求直接过滤掉.....");
        	httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
             //HTTP响应头，指定服务器允许进行跨域资源访问的"请求方法"列表，一般用在响应预检请求上
        	httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
             //HTTP响应头，指定服务器允许进行跨域资源访问的"请求头"列表，一般用在响应预检请求上
        	httpServletResponse.setHeader("Access-Control-Allow-Headers","x-auth-token,Origin, X-Requested-With, Content-Type, Accept");  
             //HTTP响应头，凡是浏览器请求中携带了身份信息，而响应头中没有返回Access-Control-Allow-Credentials: true的浏览器都会忽略此次响应
        	httpServletResponse.setHeader("Access-Control-Allow-Credentials", "false"); //true代表请求需要带cookie 
             //HTTP响应头，用在响应预检请求上，表示本次预检响应的有效时间。
        	httpServletResponse.setHeader("Access-Control-Max-Age", "3600"); 
        	httpServletResponse.setStatus(HttpStatus.ACCEPTED.value());
        	return false;  
        } 
        log.info("3.preHandle:ajax的实际请求....");
        Subject subject = SecurityUtils.getSubject();
        Serializable tokenFlag = subject.getSession().getId();//后台凭证
        String id = WebUtils.toHttp(request).getHeader("x-auth-token");
        //已经登录的重新登录，先退出登录
        if(("/ajaxLogin").equals(httpServletRequest.getRequestURI())&&tokenFlag!=null&&id!=null&&tokenFlag.toString().equals(id)){
        	subject.logout();
        }
        return true;
    }

}
